#include "Object.h"



int32 KeyValue::Uninitalize()
{
	Values::iterator first = m_values.begin();
	Values::iterator last  = m_values.end();

	int32 code = R_SUCCEED;
	for(;first!=last;++first)
	{
		if( first->second.Uninitalize() != R_SUCCEED )
			code = E_KEYVALUE_UNINIT;
	}

	return code;
}

int32 Array::Uninitalize()
{
	Values::iterator first = m_values.begin();
	Values::iterator last  = m_values.end();

	int32 code = R_SUCCEED;
	for(;first!=last;++first)
	{
		if( first->Uninitalize() != R_SUCCEED )
			code = E_KEYVALUE_UNINIT;
	}

	return code;
}

Array::iterator Array::begin()
{
	return m_values.begin();
}

Array::iterator Array::end()
{
	return m_values.end();
}

int32 Array::Add( const Object& value )
{
	m_values.push_back( value );
	return R_SUCCEED;
}

int32 Array::Initalize( const Array& value )
{
	return Initalize( value.m_values );
}

int32 Array::Initalize( const Values& value )
{
	int32 code = Uninitalize();
	if( code != R_SUCCEED )
		return code;

	m_values = value;
	return R_SUCCEED;
}
int32 KeyValue::Set( cstring& key , const Object& value )
{
	m_values[key] = value;
	return R_SUCCEED;
}

KeyValue::iterator KeyValue::begin()
{
	return m_values.begin();
}

KeyValue::iterator KeyValue::end()
{
	return m_values.end();
}

int32 KeyValue::Initialize( const KeyValue& values )
{
	return Initialize( values.m_values );
}

int32 KeyValue::Initialize( const Values& values )
{
	int32 code = Uninitalize();
	if( code != R_SUCCEED )
		return code;

	m_values = values;
	return R_SUCCEED;
}
int32 Object::Uninitalize()
{
	int32 code = R_SUCCEED;
	switch( m_type )
	{
	case OBJECT_KEYVALUE:
		code = m_value.vKeyValue->Uninitalize();
		if( code == R_SUCCEED )
			delete m_value.vKeyValue;
		break;
	case OBJECT_ARRAY:
		code = m_value.vArray->Uninitalize();
		if( code == R_SUCCEED )
			delete m_value.vArray;
		break;
	case OBJECT_STRING:
		if( m_value.vString != 0 )
			delete[] m_value.vString;
	default:
		break;
	}

	m_type = OBJECT_UNINIT;

	return code;
}

int32 Object::Initalize( const Array& value )
{
	if( Uninitalize() != R_SUCCEED )
		return E_OBJECT_UNINIT;

	m_value.vArray = new Array();

	int32 code = m_value.vArray->Initalize( value );
	if(code != R_SUCCEED)
	{
		delete m_value.vArray;
		return code;
	}

	m_type = OBJECT_ARRAY;

	return R_SUCCEED;
}

int32 Object::Initalize( const KeyValue& value )
{
	if( Uninitalize() != R_SUCCEED )
		return E_OBJECT_UNINIT;

	m_value.vKeyValue = new KeyValue();

	int32 code = m_value.vKeyValue->Initialize( value );
	if(code != R_SUCCEED)
	{
		delete m_value.vKeyValue;
		return code;
	}

	m_type = OBJECT_KEYVALUE;

	return R_SUCCEED;
}

int32 Object::Initalize( cstring& value )
{
	if( Uninitalize() != R_SUCCEED )
		return E_OBJECT_UNINIT;
	if( value.size() != 0 )
	{
		std::size_t valueSize = value.size() + 1;
		m_value.vString = new tchar[ valueSize ];
		memset(     m_value.vString , 0 , sizeof(tchar)*valueSize );
#pragma warning(push)
#pragma warning(disable:4996 )
		value.copy( m_value.vString , value.size() );
#pragma warning(pop)
	}
	else
	{
		m_value.vString = 0;
	}
	m_type = OBJECT_STRING;

	return R_SUCCEED;
}

int32 Object::Initalize( cfloat64& value )
{
	if( Uninitalize() != R_SUCCEED )
		return E_OBJECT_UNINIT;
	m_value.vFloat64 = value;
	m_type           = OBJECT_FLOAT64;

	return R_SUCCEED;
}

int32 Object::Initalize( cuint64& value )
{
	if( Uninitalize() != R_SUCCEED )
		return E_OBJECT_UNINIT;
	m_value.vUInt64 = value;
	m_type          = OBJECT_UINT64;

	return R_SUCCEED;
}

int32 Object::Initalize( cint64& value )
{
	if( Uninitalize() != R_SUCCEED )
		return E_OBJECT_UNINIT;
	m_value.vInt64 = value;
	m_type         = OBJECT_INT64;

	return R_SUCCEED;
}

int32 Object::Initalize( cuint32& value )
{
	if( Uninitalize() != R_SUCCEED )
		return E_OBJECT_UNINIT;
	m_value.vUInt32 = value;
	m_type          = OBJECT_UINT32;

	return R_SUCCEED;
}

int32 Object::Initalize( cint32& value )
{
	if( Uninitalize() != R_SUCCEED )
		return E_OBJECT_UNINIT;
	m_value.vInt32 = value;
	m_type         = OBJECT_INT32;

	return R_SUCCEED;
}

Object& Object::operator=( const Object& object )
{
	m_value = object.m_value;
	m_type  = object.m_type;
	return *this;
}

Object::Object() : m_type(OBJECT_UNINIT)
{

}